Base table
Allow users to view structured data in a clean, accessible, and simplified table format
#Table vs. Base Table
| Component | Purpose | Usage |
|---|---|---|
| Table | A feature-rich table component optimized for complex data interactions. Offers sorting, filtering, pagination, row selection, etc. | Displaying extensive datasets requiring user manipulation. |
| Base table | A streamlined table for presenting structured data without advanced interactions. | Displaying smaller datasets within dashboards or cards where complex interactions are not the primary focus. |
#Examples
#Basic usage
This will render a basic table with headers and data cells.
| Header |
|---|
foo |
bar |
<BaseTable
items={[{ text: "foo" }, { text: "bar" }]}
columns={[{ header: "Header", render: (item) => <div>{item.text}</div> }]}
withoutKeyColumn
/>#With caption
The caption provides a brief description of the table's content, aiding screen reader users and improving overall comprehension.
| Header |
|---|
foo |
bar |
<BaseTable
items={[{ text: "foo" }, { text: "bar" }]}
columns={[{ header: "Header", render: (item) => <div>{item.text}</div> }]}
caption="Caption for table"
withoutKeyColumn
/>#Expandable cells
Enable users to delve deeper into specific data points by making cells expandable. This allows for the display of additional details or actions within the cell.
Columns can be marked expandable.isExpandable is a function that gets called for each cell so you can control exactly which ones are expandable.
| Header |
|---|
foo |
<BaseTable
items={[
{ text: "foo", count: 0 },
{ text: "bar", count: 1 },
]}
columns={[
{
header: "Header",
render: (item) => <div>{item.text}</div>,
isExpandable: (item) => item.count > 0,
},
]}
withoutKeyColumn
/>#With row highlight
Visually emphasize specific rows based on certain criteria.
You can do so by providing a function as highlightRow prop which takes an item as parameter and returns a boolean which indicates whether or not to highlight an item. This function gets called for each row and adds a highlight class to those matching the criteria.
| Header | Count |
|---|---|
foo | 0 |
bar | 1 |
<BaseTable
items={[
{ text: "foo", count: 0 },
{ text: "bar", count: 1 },
]}
columns={[
{ header: "Header", render: (item) => <div>{item.text}</div>, isKeyColumn: true },
{ header: "Count", render: (item) => <div>{item.count}</div> },
]}
highlightRow={(item) => item.text === "foo"}
/>#With column summary
You can also display an extra row in the table header that contains the summary of a corresponding column. The summary content is formed by a number value and a label. The number value can also be provided as a string, enabling the use of number formatters. To display the summary of a column, use the property summary in the specifications of a column, as exemplified below.
| Header | Count |
|---|---|
1 total | |
foo | 0 |
bar | 1 |
<BaseTable
items={[
{ text: "foo", count: 0 },
{ text: "bar", count: 1 },
]}
columns={[
{ header: "Header", render: (item) => <div>{item.text}</div>, isKeyColumn: true },
{
header: "Count",
render: (item) => <div>{item.count}</div>,
summary: {
value: 1,
label: "total",
},
},
]}
/>#Keeping state
You might've noticed in the Expandable cells example that nothing happens when clicking the expander. Why? Because BaseTable is stateless. It's not its concern to know what's expanded, only to render that it is expandable. Lets hook it up so expanding works. In the below example note how we keep track of state ourselves, and push that state into BaseTable so it always renders the right thing.
| Header |
|---|
const [state, setState] = useState<BaseTableCellPosition>();
return (
<BaseTable
items={[{ text: "foo" }, { text: "bar" }]}
columns={[
{
header: "Header",
render: (item) => <div>{item.text}</div>,
isExpandable: () => true,
},
]}
withoutKeyColumn
expandedContentRenderer={() => <div>I 💓 expanded content</div>}
expandedCellPosition={state}
onExpandClick={(e, cellPosition) => {
// If the user clicks an already-expanded cell we want to collapse, i.e. reset state
if (
state &&
state.columnNum == cellPosition.columnNum &&
state.rowNum == cellPosition.rowNum
) {
setState(undefined);
return;
}
setState(cellPosition);
}}
/>
);#Loading state
When fetching data, provide a visual indicator (e.g. Spinner) to inform the user that the table is loading.
| Header | Count |
|---|---|
Loading items | |
<BaseTable<{ text: string; count: number }>
loading={true}
loadingText="Loading items"
items={[]}
columns={[
{ header: "Header", render: (item) => <div>{item.text}</div>, isKeyColumn: true },
{ header: "Count", render: (item) => <div>{item.count}</div> },
]}
/>#No data state
When no data is available, display a clear, informative message ( e.g. "Accessibility issues have been resolved."). Consider the context and provide guidance on how to resolve the issue if possible.
The noDataState is used to indicate that no data is available for display. An Empty state component with the type "reassure" and default heading is shown, but it can be overridden by another type with custom text. For guidelines please refer to the Empty state component.
| Header | Count |
|---|---|
No data to display | |
<BaseTable<{ text: string; count: number }>
items={[]}
columns={[
{ header: "Header", render: (item) => <div>{item.text}</div>, isKeyColumn: true },
{ header: "Count", render: (item) => <div>{item.count}</div> },
]}
/>#Properties
| Header 1 | Header 2 |
|---|---|
foo | bar |
bar | foo |
| Property | Description | Defined | Value |
|---|---|---|---|
columnsRequired | object[]Column configurations | ||
itemsRequired | unknown[]Items to be displayed | ||
onExpandClickOptional | functionCallback for when expander is clicked | ||
expandedContentRendererOptional | functionRenderer for content of expanded cell | ||
expandedCellPositionOptional | objectPosition of the expanded cell | ||
elementFooter displayed below table data | |||
topAlignedOptional | booleanIs the content top aligned? | ||
highlightRowOptional | functionCompare function for highlight row | ||
rowKeyOptional | functionFunction to generate a key for rows | ||
captionOptional | stringCaption for the table | ||
withoutKeyColumnOptional | booleanDoes this table not have a key column? Be sure this is the case otherwise the table is less accessible | ||
thClassNameOptional | stringClassName for th elements | ||
trClassNameOptional | stringClassName for tr elements | ||
tdClassNameOptional | stringClassName for td elements | ||
loadingOptional | booleanIs the table in a loading state? | ||
loadingTextOptional | stringOptional text to be displayed when the table is loading | ||
noDataStateOptional | elementContent to be shown when there's no data. An Empty State component is shown by default, but it can be overridden by another type with custom text. | ||
data-componentOptional | stringName of the component. Should only be set by components since it needs to stable. Used to track component usage | ||
data-observe-keyOptional | stringUnique string, used by external script e.g. for event tracking | ||
classNameOptional | stringCustom className that's applied to the outermost element (only intended for special cases) | ||
styleOptional | objectStyle object to apply custom inline styles (only intended for special cases) |
#Guidelines
#Best practices
#Do not use when
#Accessibility
Explore detailed guidelines for this component: Accessibility Specifications